<?php
require_once('bigdecimal/mathcontext.js');
require_once('bigdecimal/bigdecimal.js');
?>

/**
 * Number formatting class, the static methods provide convenient adapters
 * for BigDecimal operations.
 * 
 * Be warned, that JavaScript netively uses only 17 places precision, so if
 * you want to use precision of numbers, that exceed 17 digits, then you
 * must provide them as strings. That considers both - formatting and static
 * decimal operations.
 */
var Num = new Class({
	
	primitive: 0,
	
	bd_primitive: '0',
	
	int_part: '',
	
	dec_part: '',
	
	//--------------------------------------------------------------------------
	//--------------------------------------------------------------------------
	
	initialize: function(value)
	{
		this.int_part = '0';
		this.dec_part = null;
		
		if ( undefined != value ) {
			this.primitive = Num.strict(value);
			this.bd_primitive = Num.bdStrict(value);
			var parts = this.toString().split('.', 2);
			this.int_part = parts[0].toString();
			if ( parts[1] ) {
				this.dec_part = parts[1].toString();
			}
		}
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Returns the primitive value of Num object.
	 * @return Number
	 */
	valueOf: function()
	{
		return this.primitive;
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Returns string containing primitive value of the number.
	 * @return String
	 */
	toString: function()
	{
		return new String(this.bd_primitive);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Returns BigDecimal object.
	 * @return BigDecimal
	 */
	toBd: function()
	{
		return new BigDecimal( this.toString() );
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Converts decimal pointer to given string.
	 * @param string dec_point (optional) New decimal point separator.
	 * @return string
	 */
	formatDecPoint: function(dec_point)
	{
		if ( undefined == dec_point ) {
			dec_point = Num.locale.dec_point;
		}
		return Num._formatJoinParts(this.int_part, this.dec_part, dec_point);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Adds thousnads separator to the number inside the string.
	 * Also converts comma to dot.
	 * @param string separator_str (optional)
	 * @return string Formated number.
	 */
	formatThousandsSep: function(separator_str)
	{
		var int_part_f = Num._formatIntPartThousandsSep(
			this.int_part, separator_str
		);
		
		return Num._formatJoinParts(int_part_f, this.dec_part);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Formats the number to a minimum of given precision (number of decimal
	 * points).
	 * @param int precision (optional)
	 * @return string
	 */
	formatMinFixed: function(precision)
	{
		var dec_part_f = Num._formatDecPartMinFixed(this.dec_part, precision);
		return Num._formatJoinParts(this.int_part, dec_part_f);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Works like formatMinFixed, but rounds number if nesseccery.
	 * @param int precision (optional)
	 * @return string
	 */
	formatFixed: function(precision)
	{
		var dec_part_f = Num._formatDecPartFixed(this.dec_part, precision);
		return Num._formatJoinParts(this.int_part, dec_part_f);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Formats number like php's number_fomrat function.
	 * @param int precision
	 * @param string dec_point (optional)
	 * @param string thousands_sep (optional)
	 * @return string
	 */
	format: function(precision, dec_point, thousands_sep)
	{
		if ( undefined == precision ) {
			throw 'Must provide at least one argument';
		}
		
		var int_part_f = this.int_part;
		var dec_part_f = this.dec_part;
		
		dec_part_f = Num._formatDecPartFixed(dec_part_f, precision);
		
		if ( undefined != thousands_sep ) {
			int_part_f = Num._formatIntPartThousandsSep(
				int_part_f, thousands_sep
			);
		}
		
		return Num._formatJoinParts(int_part_f, dec_part_f, dec_point);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * For fast use of formatting numbers to standard price format.
	 * Using this for formatting in entire application allows to switch
	 * formatting quickliy everywhere.
	 * @return string 
	 */
	formatPrice: function()
	{
		return this.format(
			Num.locale.price_decimals,
			Num.locale.dec_point,
			Num.locale.thousands_sep
		);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * For fast use of formatting to standard stock format.
	 * @return string
	 */
	formatStock: function()
	{
		return this.format(
			Num.locale.stock_decimals,
			Num.locale.dec_point,
			Num.locale.thousands_sep
		);
	}
	
	//--------------------------------------------------------------------------
	
});

<?php
require_once('nrg/num.ext.js');
?>
